'use strict';
const BaseService = require('./base');
const ResponseUtil = require('../utils/ResponseUtil');
const StringUtil = require('../utils/StringUtil');
const HelperUtil = require('../utils/HelperUtil');
const VRCE = require('../utils/ViewResultCodeEnum');
const Constant = require('../config/Constant');

class TenantService extends BaseService {


    async checkTenantNameUnique(tenant) {
        let id = tenant.id || 0;
        let sql = 'select * from sys_tenant where tenant_name=? limit 1';
        let info = await this.executeSqlFirst(sql, [tenant.tenantName]);
        if (info != null && info.id != id) {
            return Constant.NOT_UNIQUE;
        }
        return Constant.UNIQUE;
    }


    async checkPhoneUnique(tenant) {
        let id = tenant.id || 0;
        let sql = 'select * from sys_tenant where phone=? limit 1';
        let info = await this.executeSqlFirst(sql, [tenant.phone]);
        if (info != null && info.id != id) {
            return Constant.NOT_UNIQUE;
        }
        return Constant.UNIQUE;
    }


    async addTenant(tenant) {
        if (Constant.NOT_UNIQUE == (await this.checkTenantNameUnique(tenant))) {
            return ResponseUtil.resError(VRCE.ADMIN_TENANT_NAME_EXIST[1], VRCE.ADMIN_TENANT_NAME_EXIST[0]);
        }
        if (Constant.NOT_UNIQUE == (await this.checkPhoneUnique(tenant))) {
            return ResponseUtil.resError(VRCE.ADMIN_TENANT_PHONE_EXIST[1], VRCE.ADMIN_TENANT_PHONE_EXIST[0]);
        }
        let conn = await this.app.mysql.beginTransaction();

        try {

            let loginUserInfo = this.ctx.getLoginInfo();
            let operatorType = loginUserInfo.operatorType;
            let operatorId = loginUserInfo.operatorId;
            let createBy = loginUserInfo.createBy;


            let tenantParams = {
                id: StringUtil.getUUIDV2(),
                tenant_name: tenant.tenantName,
                social_credit_code: tenant.socialCreditCode,
                legal_person: tenant.legalPerson,
                phone: tenant.phone,
                email: tenant.email,
                status: tenant.status,
                create_by: createBy,
                create_by_id: operatorId,
                update_by: createBy,
                update_by_id: operatorId,
                remark: tenant.remark,
                del_flag:0
            };


            let insertTenantResult = await conn.insert('sys_tenant', tenantParams);

            if (!insertTenantResult.affectedRows) {
                throw Error('insert tenant error');
            }

            if (Constant.NOT_UNIQUE == (await this.ctx.service.sysuser.checkPhoneUnique(tenant))) {
                return ResponseUtil.resError(VRCE.ADMIN_USER_PHONE_EXIST[1], VRCE.ADMIN_USER_PHONE_EXIST[0]);
            }

            let userParams = {
                tenant_id: tenantParams.id,
                avatar: tenant.avatar,
                user_no: StringUtil.getUUID(),
                user_name: tenant.tenantName,
                nick_name: tenant.tenantName,
                phone: tenant.phone,
                email: tenant.email,
                password: (await HelperUtil.bcryptHashPassword(tenant.password)),
                status: tenant.status || 0,
                del_flag: 0,
                remark: tenant.remark,
                create_by: createBy,
                create_by_id: operatorId,
                update_by: createBy,
                update_by_id: operatorId,
                create_time: new Date(),
                update_time: new Date()
            };

            let insertUserResult = await conn.insert('sys_user', userParams);

            if (!insertUserResult.affectedRows) {
                throw Error('insert tenant user error');
            }


            let sql = 'update sys_tenant set user_id=? where id=?';
            let size = await this.executeSqlSucc(sql,[insertUserResult.insertId,tenantParams.id],conn);
            if(size <=0){
                throw Error('update tenant user id error');
            }

            await conn.commit();
            return tenantParams.id;

        } catch (e) {
            this.ctx.app.logger.error('insertTenant error', e.message);
            await conn.rollback();
            throw Error(e.message);
        }
    }

    async selectTenantById(tenantId){
        let sql = 'select * from sys_tenant where id=? ';
        let result = await this.executeSqlFirst(sql,[tenantId]);
        return result;
    }

    async editTenant(tenant) {
        if (Constant.NOT_UNIQUE == (await this.checkTenantNameUnique(tenant))) {
            return ResponseUtil.resError(VRCE.ADMIN_TENANT_NAME_EXIST[1], VRCE.ADMIN_TENANT_NAME_EXIST[0]);
        }
        if (Constant.NOT_UNIQUE == (await this.checkPhoneUnique(tenant))) {
            return ResponseUtil.resError(VRCE.ADMIN_TENANT_PHONE_EXIST[1], VRCE.ADMIN_TENANT_PHONE_EXIST[0]);
        }

        let object = await this.selectTenantById(tenant.id);
        if(!object){
            return ResponseUtil.resError('租户不存在');
        }



        let conn = await this.app.mysql.beginTransaction();

        try {

            let loginUserInfo = this.ctx.getLoginInfo();
            let operatorType = loginUserInfo.operatorType;
            let operatorId = loginUserInfo.operatorId;
            let createBy = loginUserInfo.createBy;

            let tenantParams = {
                tenant_name: tenant.tenantName,
                legal_person: tenant.legalPerson,
                social_credit_code:tenant.socialCreditCode,
                phone: tenant.phone,
                email: tenant.email,
                status: tenant.status || 0,
                update_by: createBy,
                update_by_id: operatorId,
                remark: tenant.remark
            };
            if(object.roleKey){
                delete userParams.role_key
            }
            const options = {
                where: {
                    id: tenant.id
                }
            };
            let updateUserResult = await conn.update('sys_tenant', tenantParams, options);

            if (!updateUserResult.affectedRows) {
                throw Error('update tenant error');
            }

            let userParams = {
                user_name: tenant.tenantName,
                nick_name: tenant.tenantName,
                phone: tenant.phone,
                email: tenant.email,
                status: tenant.status || 0,
                remark: tenant.remark,
                update_by: createBy,
                update_by_id: operatorId,
                update_time: new Date()
            };

            const options2 = {
                where: {
                    user_id: tenant.userId
                }
            };
            let updateUserResult2 = await conn.update('sys_user', userParams, options2);

            if (!updateUserResult2.affectedRows) {
                throw Error('update user error');
            }


            await conn.commit();
            return tenant.id;

        } catch (e) {
            this.ctx.app.logger.error('updateUser error', e.message);
            await conn.rollback();
            throw Error(e.message);
        }
    }


    async getTenantList({keyword, beginTime, endTime, pageNum, pageSize, phone, status, tenantName, delFlag, noSelectCount, email, roleKey}) {
        let loginUserInfo = this.ctx.getLoginInfo();
        let operatorType = loginUserInfo.operatorType;
        let operatorId = loginUserInfo.operatorId;
        let createBy = loginUserInfo.createBy;
        let isAdmin = loginUserInfo.isAdmin;


        let sql_list = `select u.* `;
        let sql_count = `select count(*) as count `;
        let sql = ` from sys_tenant u where 1=1 `;

        let wheres = [
            {column: 'phone', value: phone, options: {tname: 'u'}},
            {column: 'tenant_name', value: tenantName, options: {tname: 'u', condition: 'like'}},
            {column: 'email', value: email, options: {tname: 'u', condition: 'like'}},
            {column: 'status', value: status, options: {tname: 'u'}},
            {column: 'create_time', value: beginTime, options: {tname: 'u', condition: '>=', format: true}},
            {column: 'create_time', value: endTime, options: {tname: 'u', condition: '<', format: true}},
            {column: 'del_flag', value: delFlag, options: {tname: 'u'}}
        ];

        let formatSqlResult = this.formatSqlWhere(sql, wheres);

        sql = formatSqlResult[0];

        let options = formatSqlResult[1];

        if (keyword) {
            sql += ` AND (u.tenant_name like "%"?"%" or u.phone like "%"?"%" ) `;
            options.push(keyword);
            options.push(keyword);
        }


        sql_count += sql;

        sql += ` order by u.create_time desc `;

        sql_list += sql;

        if (noSelectCount != true) {
            sql_list = this.addMysqlPageSize(sql_list, pageNum, pageSize);
        }

        let list = await this.executeSql(sql_list, options);

        let countRet = {
            count: 0
        };
        if (noSelectCount != true) {
            countRet = await this.executeSqlFirst(sql_count, formatSqlResult[1]);
        }

        return {list: list, total: countRet.count};
    }

}

module.exports = TenantService;
